#ifndef EVENTMANAGER_H
#define EVENTMANAGER_H

#include "Export.h"
#include "GL/glfw.h"

#define NBKEYS 1024
#define NBMOUSEBUTTONS 10

namespace glow
{
	class SHARED EventManager
	{
		public:

		/**
		 * Initiate the EventManager
		 *\param true if the keyrepeat is activate, else false
		 *\param true is the stickykeys is activate, else false
		 *\param true if the stickyMouseButtons is activate, else false
		 **/
		void init(bool keyRepeat = true, bool stickykeys = true, bool stickyMouseButtons = true);

		/**
		 *	Update of the event.
		 *  Must be call in the main loop
		 **/
		void getEvent();

		/**
		 *	Try if the key is pressed (once detect)
		 *\param the key tried
		 *\return true if the keys is pressed, else false
		 **/
		bool isKeyDownOnce(int key);
		
		/**
		 *	Try if the key is pressed
		 *\param the key tried
		 *\return true if the keys is pressed, else false
		 **/
		bool isKeyDown(int key) const;

		/**
		 *	Try if the button is pressed
		 *\param the button pressed
		 *\return true if the button is pressed, else false
		 **/
		bool isMouseButtonUp(int button) const;

		/**
		 * Get the mouse abscisse position
		 *\return the mouse X position
		 **/
		int getMouseX() const;
		/**
		 *	Get the mouse ordonate position
		 *\return the mouse Y position
		 **/
		int getMouseY()const;
		/**
		 *	Get the relative abscisse position
		 *\return the mouse X relative position
		 **/
		int getRelMouseX() const;
		/**
		 *	Get the relative ordonate position
		 *\return the mouse Y relative position
		 **/
		int getRelMouseY() const;

		/**
		 *\return true if the the application must be closed, else false
		 **/
		bool quit() const;

		/**
		 *	Link the action with the key
		 *\param the key
		 *\param the action link
		 **/
		void eventKeyCB(int key, int action);
		/**
		 *	Update the relative position of the mouse
		 *\param the X position of the mouse
		 *\param the Y position of the mouse
		 **/
		void eventMouseCB(int x, int y);
		/**
		 *	Link the action with the button
		 *\param the key
		 *\param the action link
		 **/
		void eventMouseButtonCB(int button, int action);
		
		/**
		 *	SINGLETON
		 *\return pointer to the current instance of the EventManager (SINGLETON)
		 **/
		static EventManager *getInstance();
		/**
		 *	Call the destructor of the current instance
		 **/
		static void destroy();

		private:

		EventManager();
		~EventManager();
		
		/**
		 *	The keyDown table
		 */
		int _keyDown[NBKEYS];

		/**
		 *	The keyOnce table
		 */
		int _keyOnce[NBKEYS];
		
		/**
		 *	The mouse button table
		 */
		int _mouseButton[NBMOUSEBUTTONS];

		/**
		 *	The abscisse position of the mouse
		 */
		int _mouseX; 
		/**
		 *	The ordonate position of the mouse
		 */
		int _mouseY;
		/**
		 *	The old abscisse position of the mouse
		 */
		int _oldMouseX;
		/**
		 *	The old ordonate position of the mouse
		 */
		int _oldMouseY;
		/**
		 *	The relative abscisse position of the mouse
		 */
		int _relX;
		/**
		 * The relative ordonate position of the mouse
		 */
		int _relY;

		/**
		 *	True if a close event is actived, else false
		 */
		bool _quit;
		
		/**
		 *	SINGLETON : pointer to the current instance
		 */
		static EventManager *_inst;
	};
}

#endif
